﻿//<TunynetCopyright>
//--------------------------------------------------------------
//<copyright>青岛拓宇网络科技有限公司 2005-2008</copyright>
//<version>V0.5</verion>
//<createdate>2008-3-4</createdate>
//<author>mazq</author>
//<email>mazq@tunynet.com</email>
//<log date="2008-3-4">创建</log>
//--------------------------------------------------------------
//</TunynetCopyright>


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web;
using System.ComponentModel;
using System.Web.UI.WebControls;
using System.Configuration;

namespace ChinaCustoms.Qingdao.Workflow.Controls
{
    /// <summary>
    /// 需要外部Skin 或 页面模版的 Web控件基类
    /// </summary>
    [
    ParseChildren(true),
    PersistChildren(false),
    ]
    public abstract class TemplatedWebControl : WebControl, INamingContainer
    {
        #region Composite Controls

        /// <exclude/>
        public override ControlCollection Controls
        {
            get
            {
                this.EnsureChildControls();
                return base.Controls;
            }
        }

        /// <exclude/>
        public override void DataBind()
        {
            this.EnsureChildControls();
        }

        #endregion

        #region External Skin

        protected virtual string SkinFolder
        {
            get
            {
                if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["WorkflowControlSkinFolder"]))
                    return ConfigurationManager.AppSettings["WorkflowControlSkinFolder"];
                else
                    return "~/Utility/WorkflowControlSkins/";
            }
        }

        private String SkinPath
        {
            get { return this.SkinFolder + ExternalSkinFileName; }
        }

        /// <summary>
        /// Gets the name of the skin file to load from
        /// </summary>
        protected virtual String ExternalSkinFileName
        {
            get
            {
                if (SkinName == null)
                    return CreateExternalSkinFileName(null);

                return SkinName;
            }
            set { SkinName = value; }
        }

        string skinName;
        public string SkinName
        {
            get { return skinName; }
            set { skinName = value; }
        }

        protected virtual string CreateExternalSkinFileName(string path)
        {
            return CreateExternalSkinFileName(path, "Skin-" + this.GetType().Name);
        }

        protected virtual string CreateExternalSkinFileName(string path, string name)
        {
            if (path != null && !path.EndsWith("/"))
                path += "/";

            return string.Format("{0}{1}.ascx", path, name);
        }


        private Boolean SkinFolderExists
        {
            get
            {
                HttpContext context = HttpContext.Current;
                if (context != null)
                {
                    String folderPath = context.Server.MapPath(this.SkinFolder);
                    return System.IO.Directory.Exists(folderPath);
                }
                return true;
            }
        }

        private Boolean SkinFileExists
        {
            get
            {
                HttpContext context = HttpContext.Current;
                if (context != null)
                {
                    String filePath = context.Server.MapPath(this.SkinPath);
                    return System.IO.File.Exists(filePath);
                }
                return true;
            }
        }

        #endregion


        #region Public Properties

        /// <summary>
        /// The template used to override the default UI of the control.
        /// </summary>
        /// <remarks>
        /// All serverside controls that are in the default UI must exist and have the same ID's.
        /// </remarks>
        [
        Browsable(false),
        DefaultValue(null),
        Description("TODO SkinTemplate Description"),
        PersistenceMode(PersistenceMode.InnerProperty),
        ]
        public ITemplate SkinTemplate
        {
            get { return _skinTemplate; }
            set
            {
                _skinTemplate = value;
                ChildControlsCreated = false;
            }
        }
        private ITemplate _skinTemplate;

        #endregion

        public override void RenderBeginTag(HtmlTextWriter writer)
        {
            //we don't need a span tag
        }

        /// <summary>
        /// No End Span
        /// </summary>
        public override void RenderEndTag(HtmlTextWriter writer)
        {
            //we don't need a span tag
        }

        /// <exclude/>
        public override Control FindControl(string id)
        {
            Control ctrl = base.FindControl(id);
            if (ctrl == null && this.Controls.Count == 1)
                ctrl = this.Controls[0].FindControl(id);

            return ctrl;
        }

        /// <summary>
        /// Loads the skin file from the users current theme
        /// </summary>
        /// <returns></returns>
        protected virtual bool LoadThemedControl()
        {
            if (SkinFolderExists)
            {
                if (SkinFileExists && this.Page != null)
                {
                    Control skin = this.Page.LoadControl(this.SkinPath);
                    skin.ID = "_";
                    this.Controls.Add(skin);
                    return true;
                }
            }

            return false;
        }

        /// <exclude/>
        protected override void CreateChildControls()
        {
            Controls.Clear();

            Boolean _skinLoaded = false;

            // 1) Next, look for an inline template
            if (SkinTemplate != null)
            {
                SkinTemplate.InstantiateIn(this);
                _skinLoaded = true;
            }

            // 2) A custom theme setting is the most important
            if (!_skinLoaded)
                _skinLoaded = LoadThemedControl();

            // 3) If none of the skin locations were successful, throw.
            if (!_skinLoaded)
                throw new Exception("Skin File not found");

            AttachChildControls();
        }

        /// <summary>
        /// Override this method to attach templated or external skin controls to local references.
        /// </summary>
        /// <remarks>
        /// This will only be called if the non-default skin is used.
        /// </remarks>
        protected abstract void AttachChildControls();

        protected override void Render(HtmlTextWriter writer)
        {
            if (EnableSourceMark)
                SourceMarker(true, writer);

            base.Render(writer);

            if (EnableSourceMark)
                SourceMarker(false, writer);
        }

        [System.Diagnostics.Conditional("DEBUG")]
        protected void SourceMarker(bool isStart, HtmlTextWriter writer)
        {
            if (isStart)
            {
                writer.WriteLine("<!-- Start: {0} -->", this.GetType());

                if (System.IO.File.Exists(HttpContext.Current.Server.MapPath(this.SkinPath)))
                    writer.WriteLine("<!-- Skin Path: {0} -->", this.SkinPath);
                else if (SkinTemplate != null)
                    writer.WriteLine("<!-- Inline Skin: {0} -->", true);

            }
            else
                writer.WriteLine("<!-- End: {0} -->", this.GetType());
        }

        /// <summary>
        /// 是否启用Skin文件跟踪
        /// </summary>
        protected virtual bool EnableSourceMark
        {
            get { return true; }
        }


    }
}
